﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Castle.MicroKernel;
using Castle.MicroKernel.Lifestyle;
using MassTransit;
using MassTransit.Pipeline;
using MassTransit.RabbitMqTransport;
using MassTransit.Util;
using UserManagement.Core;
using UserManagement.Events;
using UserManagement.Service.Observers;

namespace UserManagement.Service
{
    public class UserManagementServiceBusConfiguration: BusConfiguration
    {
        private UserManagementServiceBusConfiguration() { }

        public override string RabbitMqAddress { get; } = "rabbitmq://localhost/";
        public override string QueueName { get; } = "UserManagementServiceQueue";
        public override string RabbitMqUserName { get; } = "guest";
        public override string RabbitMqPassword { get; } = "guest";

        private static IBus _bus;

        public static IBus BusInstance => _bus ?? (_bus = new UserManagementServiceBusConfiguration().CreateBus());

        public override Action<IRabbitMqBusFactoryConfigurator, IRabbitMqHost> Configuration
        {
            get
            {
                return (cfg, host) =>
                {
                    cfg.UseRetry(Retry.Interval(3, TimeSpan.FromMinutes(1)));
                    cfg.UseRateLimit(1000, TimeSpan.FromSeconds(1));
                    cfg.ReceiveEndpoint(host, QueueName, e =>
                    {
                        e.UseMessageScope();
                        //1. register consumers by manually
                        //e.Consumer<UserCreatedEventConsumer>();
                        //e.Consumer<UserUpdatedEventComsumer>();

                        //2. register comsumers by container
                        e.LoadFrom(ApplicationBootstrapper.Container);
                    });
                };
            }
        }

        public override Action<IBus> ConnectObservers
        {
            get
            {
                return bus =>
                {
                    bus.ConnectReceiveObserver(new ReceiveObserver());
                    bus.ConnectConsumeMessageObserver(new ConsumeObserver<UserCreatedEvent>());
                };
            }
        }
    }
}